package com.alili_tv.system.controller;

import com.alili_tv.system.common.BaseContext;
import com.alili_tv.system.common.LoginRequired;
import com.alili_tv.system.common.R;
import com.alili_tv.system.common.SessionCache;
import com.alili_tv.system.entity.Likes;
import com.alili_tv.system.entity.Message;
import com.alili_tv.system.entity.User;
import com.alili_tv.system.exception.BusinessException;
import com.alili_tv.system.service.*;
import com.alili_tv.system.utils.CommonUtils;
import com.alili_tv.system.utils.JwtUtils;
import com.alili_tv.system.utils.ValidUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author baomidou
 * @since 2023-03-17
 */
@RestController
@RequestMapping(value = "/user", produces = "application/json")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private LikesService likesService;

    @Resource
    private VideoService videoService;

    @Resource
    private MessageService messageService;

    @Resource
    private ValidUtils validUtils;

    @Resource
    private RedisTemplate<String, String> redisTemplate;


    /**
     * 用户登录，只用来设置token，获取用户信息通过autologin获取
     *
     * @param user
     * @param session
     * @return
     */
    @PostMapping("/login")
    public R<String> login(@RequestBody User user, HttpSession session) {
        // 数据验证
        if (user.getAccount() == null || user.getAccount().trim().equals("")) {
            return R.error("账号不能为空");
        }

        // 判断是验证码登录还是密码登录
        if (user.getCode() != null && !"".equals(user.getCode())) {
            // 验证码登录
            user = userService.loginWithCode(user);
        } else if (user.getPassword() != null && !"".equals(user.getPassword())) {
            // 密码登录
            user = userService.loginWithPwd(user);
        } else {
            return R.error("错误的登录方式");
        }

//        // 添加session，持久登录
//        SessionCache.cache(session, user.getId());

        // 添加token(存放用户id，有效期为3天)，持久登录
        String token = JwtUtils.createToken(user.getId());

        return R.success(token);
    }

    @GetMapping("/autoLogin")
    public R<?> autoLogin(HttpServletRequest request) {

        // 获取请求头里的token
        String token = request.getHeader("token");
        // 解析token并获取里面的信息（userId）
        Long userId = JwtUtils.getVal(token);
        // 若获取不到id 或者jwt过期则返回
        if (userId == null || !JwtUtils.validate(token)) {
            return R.common();
        }
        // 查询用户
        User user = userService.getById(userId);
        // 若用户不存在返回提示信息
        if (user == null) {
            return R.common();
        }

        // 判断用户是否有新消息
        user.setNewMessage(messageService.hasNew(user.getId()));
        // 判断用户是否有新动态
        user.setNewDynamic(videoService.hasNew(user.getId()));

        // 每次自动登录刷新token
        token = JwtUtils.createToken(user.getId());
        user.setToken(token);

        return R.success(user);
    }

    @PostMapping("/logout")
    public R<String> login(HttpSession session) {
        SessionCache.delete(session);
        return R.success("success");
    }

    @GetMapping("/{userId}")
    public R<User> getById(@PathVariable Long userId) {
        User user = userService.getById(userId);
        if (user == null)
            return R.error("用户已注销");
        else
            return R.success(user);
    }

    /**
     * 修改用户频道排序
     * @param channelList 使用Object接收，转成json字符串，放在数据库
     * @return
     */
    @LoginRequired
    @PutMapping("/updateChannel")
    public R<String> updateChannel(@RequestBody Object channelList) {
        ObjectMapper mapper = new ObjectMapper();
        String s;
        try {
            // 转为json
            s = mapper.writeValueAsString(channelList);
        } catch (JsonProcessingException e) {
            throw new BusinessException("数据异常");
        }
        if (s == null || "".equals(s)) return R.error("数据异常");

        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .set(User::getChannelSort, s)
                .eq(User::getId, BaseContext.getCurrentId());
        boolean update = userService.update(updateWrapper);

        return update ? R.success("修改成功") : R.error("修改失败");
    }

    /**
     * 修改普通信息
     *
     * @param user
     * @return
     */
    @PutMapping
    @LoginRequired
    public R<String> updateCommonInfo(@RequestBody User user) {
        // 数据校验
        if ((user.getName() == null || user.getName().trim().equals("")) && user.getGender() == null) {
            return R.common();
        }

        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        if (user.getName() != null) {
            String userName = user.getName().trim();
            if (userName.length() >= 2) {
                updateWrapper.set(User::getName, userName);
            } else {
                return R.error("用户名长度不能低于2");
            }
        }
        updateWrapper
                .set(user.getGender() != null, User::getGender, user.getGender())
                .eq(User::getId, BaseContext.getCurrentId());
        updateWrapper.isEmptyOfNormal();
        userService.update(updateWrapper);
        return R.success("修改成功");
    }


    /**
     * 修改手机号或邮箱或密码
     *
     * @param user
     * @return
     */
    @LoginRequired
    @PutMapping("/updateSensitive")
    public R<String> updateSensitive(@RequestBody User user) {
        // 判断输入的手机号或者邮箱是否是自己的
        R<String> rStr = this.validSelfAccount(user);
        if (rStr.getCode() == 1) {
            return rStr;
        }

        // 匹配原手机号或邮箱发送的验证码
        if (!validUtils.validCode(user.getAccount(), user.getCode(), false)) {
            return R.error("验证码错误");
        }

        // 准备修改
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, BaseContext.getCurrentId());

        if (user.getPassword() != null) {
            // 修改密码
            if (user.getPassword().length() < 6 || user.getPassword().length() > 18) {
                return R.error("密码长度为6至18位");
            } else {
                // 添加修改字段 -- 密码(加密)
                String password = CommonUtils.md5Encryption(user.getPassword());
                updateWrapper.set(User::getPassword, password);
            }
        } else if (ValidUtils.isValidPhone(user.getPhone())) {
            // 修改手机号
            // 匹配新手机号发送的验证码
            if (validUtils.validCode(user.getPhone(), user.getSecondCode(), false)) {
                // 添加修改字段 -- 手机号
                updateWrapper.set(User::getPhone, user.getPhone());
            } else {
                return R.error("验证码错误");
            }

        } else if (ValidUtils.isValidEmail(user.getEmail())) {
            // 修改邮箱
            // 匹配新邮箱发送的验证码
            if (validUtils.validCode(user.getEmail(), user.getSecondCode(), false)) {
                // 添加修改字段 -- 邮箱
                updateWrapper.set(User::getEmail, user.getEmail());
            } else {
                return R.error("验证码错误");
            }
        } else {
            return R.common();
        }

        // 执行修改
        userService.update(updateWrapper);

        // 删除验证码缓存
        if (user.getAccount() != null) redisTemplate.delete(user.getAccount());
        if (user.getPhone() != null) redisTemplate.delete(user.getPhone());
        if (user.getEmail() != null) redisTemplate.delete(user.getEmail());
        return R.success("修改成功");
    }

    private R<String> validSelfAccount(User userInput) {

        Long userId = BaseContext.getCurrentId();
        // 查询用户的手机号或者邮箱号
        User userSelected = userService.getTelAndMailById(userId);
        if (userInput == null || userSelected == null) {
            return R.error("验证方式不能为空");
        }

        if (ValidUtils.isValidEmail(userInput.getAccount())) {
            // 是邮箱
            // 比对输入的账号是否是自己的
            if (!userInput.getAccount().equals(userSelected.getEmail())) {
                return R.error("邮箱错误");
            }
        } else if (ValidUtils.isValidPhone(userInput.getAccount())) {
            // 是手机号
            if (!userInput.getAccount().equals(userSelected.getPhone())) {
                return R.error("手机号错误");
            }
        } else {
            return R.error("手机号或邮箱错误格式错误");
        }

        return R.success("success");
    }


}
